/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define private public
#define protected public
#include "window_adapter.h"
#undef private
#include <gtest/gtest.h>
#include <functional>

#include <string>
#include <vector>

#include "global.h"

namespace OHOS {
namespace MiscServices {
using namespace testing::ext;

class MockWindowAdapter : public WindowAdapter {
public:
    void MockRegisterCallingWindowInfoChangedListener(std::function<void(OHOS::Rosen::CallingWindowInfo)> callback) {
        WindowAdapter::RegisterCallingWindowInfoChangedListener(callback);
    }
};

class WindowAdapterMockTest : public testing::Test {
public:
    static void SetUpTestCase() {
        IMSA_HILOGI("WindowAdapterMockTest::SetUpTestCase");
    }

    static void TearDownTestCase() {
        IMSA_HILOGI("WindowAdapterMockTest::TearDownTestCase");
    }

    void SetUp() override {
        IMSA_HILOGI("WindowAdapterMockTest::SetUp");
        mockWindowAdapter = new MockWindowAdapter();
    }

    void TearDown() override {
        IMSA_HILOGI("WindowAdapterMockTest::TearDown");
        delete mockWindowAdapter;
    }

    void TestRegisterCallingWindowInfoChangedListener() {
        WindowDisplayChangeHandler callback = [](OHOS::Rosen::CallingWindowInfo callingWindowInfo) {
            IMSA_HILOGD("callback result:%{public}s",
                WindowDisplayChangeListener::CallingWindowInfoToString(callingWindowInfo).c_str());
        };
        mockWindowAdapter->MockRegisterCallingWindowInfoChangedListener(callback);
    }

private:
    MockWindowAdapter* mockWindowAdapter;
};

/**
 * @tc.name: WindowAdapterMockTest_StoreAllDisplayGroupInfos_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_StoreAllDisplayGroupInfos_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_StoreAllDisplayGroupInfos_001 start.");
    int32_t result = mockWindowAdapter->StoreAllDisplayGroupInfos();
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
}

/**
 * @tc.name: WindowAdapterMockTest_GetAllFocusWindowInfos_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_GetAllFocusWindowInfos_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_GetAllFocusWindowInfos_001 start.");
    std::vector<FocusChangeInfo> focusWindowInfos;
    int32_t result = mockWindowAdapter->GetAllFocusWindowInfos(focusWindowInfos);
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
}

/**
 * @tc.name: WindowAdapterMockTest_GetDisplayGroupIdByDisplayId_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_GetDisplayGroupIdByDisplayId_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_GetDisplayGroupIdByDisplayId_001 start.");
    uint64_t displayId = 123456;
    uint64_t result = mockWindowAdapter->GetDisplayGroupId(displayId);
    EXPECT_EQ(result, DEFAULT_DISPLAY_GROUP_ID);
}

/**
 * @tc.name: WindowAdapterMockTest_IsDefaultDisplayGroup_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_IsDefaultDisplayGroup_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_IsDefaultDisplayGroup_001 start.");
    uint64_t displayId = 123456;
    bool result = mockWindowAdapter->IsDefaultDisplayGroup(displayId);
    EXPECT_TRUE(result);
}

/**
 * @tc.name: WindowAdapterMockTest_GetDisplayGroupIdByWindowId_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_GetDisplayGroupIdByWindowId_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_GetDisplayGroupIdByWindowId_001 start.");
    uint32_t windowId = 123456;
    uint64_t result = mockWindowAdapter->GetDisplayGroupId(windowId);
    EXPECT_EQ(result, DEFAULT_DISPLAY_GROUP_ID);
}

/**
 * @tc.name: WindowAdapterMockTest_GetAllDisplayGroupInfos_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_GetAllDisplayGroupInfos_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_GetAllDisplayGroupInfos_001 start.");
    std::unordered_map<uint64_t, uint64_t> displayGroupIds;
    std::vector<FocusChangeInfo> focusWindowInfos;
    int32_t result = mockWindowAdapter->GetAllDisplayGroupInfos(displayGroupIds, focusWindowInfos);
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
}

/**
 * @tc.name: WindowAdapterMockTest_SetDisplayGroupIds_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_SetDisplayGroupIds_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_SetDisplayGroupIds_001 start.");
    std::unordered_map<uint64_t, uint64_t> displayGroupIds;

    displayGroupIds[100] = 200;
    displayGroupIds[300] = 400;

    mockWindowAdapter->SetDisplayGroupIds(displayGroupIds);

    uint64_t result1 = mockWindowAdapter->GetDisplayGroupId(100);
    EXPECT_EQ(result1, 200);
    
    uint64_t result2 = mockWindowAdapter->GetDisplayGroupId(300);
    EXPECT_EQ(result2, 400);

    uint64_t result3 = mockWindowAdapter->GetDisplayGroupId(999);
    EXPECT_EQ(result3, DEFAULT_DISPLAY_GROUP_ID);
}

/**
 * @tc.name: WindowAdapterMockTest_SetFocusWindowInfos_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_SetFocusWindowInfos_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_SetFocusWindowInfos_001 start.");
    std::vector<Rosen::FocusChangeInfo> focusWindowInfos;

    FocusChangeInfo info1;
    info1.windowId_ = 100;
    info1.displayGroupId_ = 200;
    info1.displayId_ = 300;
    info1.pid_ = 400;
    
    FocusChangeInfo info2;
    info2.windowId_ = 500;
    info2.displayGroupId_ = 600;
    info2.displayId_ = 700;
    info2.pid_ = 800;
    
    focusWindowInfos.push_back(info1);
    focusWindowInfos.push_back(info2);

    mockWindowAdapter->SetFocusWindowInfos(focusWindowInfos);

    std::vector<FocusChangeInfo> retrievedInfos;
    int32_t result = mockWindowAdapter->GetAllFocusWindowInfos(retrievedInfos);
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
    EXPECT_EQ(retrievedInfos.size(), 2);
    
    if (!retrievedInfos.empty()) {
        EXPECT_EQ(retrievedInfos[0].windowId_, 100);
        EXPECT_EQ(retrievedInfos[0].displayGroupId_, 200);
        EXPECT_EQ(retrievedInfos[0].displayId_, 300);
        EXPECT_EQ(retrievedInfos[0].pid_, 400);
        
        EXPECT_EQ(retrievedInfos[1].windowId_, 500);
        EXPECT_EQ(retrievedInfos[1].displayGroupId_, 600);
        EXPECT_EQ(retrievedInfos[1].displayId_, 700);
        EXPECT_EQ(retrievedInfos[1].pid_, 800);
    }
}

/**
 * @tc.name: WindowAdapterMockTest_OnDisplayGroupInfoChanged_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_OnDisplayGroupInfoChanged_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_OnDisplayGroupInfoChanged_001 start.");
    uint64_t displayId = 123456;
    uint64_t displayGroupId = 789012;
    bool isAdd = true;

    mockWindowAdapter->OnDisplayGroupInfoChanged(displayId, displayGroupId, isAdd);

    uint64_t result = mockWindowAdapter->GetDisplayGroupId(displayId);
    EXPECT_EQ(result, displayGroupId);

    bool isDefault = mockWindowAdapter->IsDefaultDisplayGroup(displayId);
    EXPECT_FALSE(isDefault);

    bool isDelete = false;
    mockWindowAdapter->OnDisplayGroupInfoChanged(displayId, displayGroupId, isDelete);

    uint64_t resultAfterDelete = mockWindowAdapter->GetDisplayGroupId(displayId);
    EXPECT_EQ(resultAfterDelete, DEFAULT_DISPLAY_GROUP_ID);

    bool isDefaultAfterDelete = mockWindowAdapter->IsDefaultDisplayGroup(displayId);
    EXPECT_TRUE(isDefaultAfterDelete);
}

/**
 * @tc.name: WindowAdapterMockTest_OnFocused_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_OnFocused_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_OnFocused_001 start.");
    FocusChangeInfo focusWindowInfo;
    focusWindowInfo.windowId_ = 123456;
    focusWindowInfo.displayGroupId_ = 789012;
    focusWindowInfo.displayId_ = 345678;
    focusWindowInfo.pid_ = 901234;

    mockWindowAdapter->OnFocused(focusWindowInfo);

    std::vector<FocusChangeInfo> retrievedInfos;
    int32_t result = mockWindowAdapter->GetAllFocusWindowInfos(retrievedInfos);
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
    EXPECT_EQ(retrievedInfos.size(), 1);
    
    if (!retrievedInfos.empty()) {
        EXPECT_EQ(retrievedInfos[0].windowId_, focusWindowInfo.windowId_);
        EXPECT_EQ(retrievedInfos[0].displayGroupId_, focusWindowInfo.displayGroupId_);
        EXPECT_EQ(retrievedInfos[0].displayId_, focusWindowInfo.displayId_);
        EXPECT_EQ(retrievedInfos[0].pid_, focusWindowInfo.pid_);
    }

    FocusChangeInfo focusWindowInfo2;
    focusWindowInfo2.windowId_ = 123456;
    focusWindowInfo2.displayGroupId_ = 789013;
    focusWindowInfo2.displayId_ = 345679;
    focusWindowInfo2.pid_ = 901235;
    
    mockWindowAdapter->OnFocused(focusWindowInfo2);

    int32_t result2 = mockWindowAdapter->GetAllFocusWindowInfos(retrievedInfos);
    EXPECT_EQ(result2, ErrorCode::NO_ERROR);
    EXPECT_EQ(retrievedInfos.size(), 1);
    
    if (!retrievedInfos.empty()) {
        EXPECT_EQ(retrievedInfos[0].windowId_, focusWindowInfo2.windowId_);
        EXPECT_EQ(retrievedInfos[0].displayGroupId_, focusWindowInfo2.displayGroupId_);
        EXPECT_EQ(retrievedInfos[0].displayId_, focusWindowInfo2.displayId_);
        EXPECT_EQ(retrievedInfos[0].pid_, focusWindowInfo2.pid_);
    }
}

/**
 * @tc.name: WindowAdapterMockTest_OnUnFocused_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_OnUnFocused_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_OnUnFocused_001 start.");
    FocusChangeInfo focusWindowInfo;
    focusWindowInfo.windowId_ = 123456;
    focusWindowInfo.displayGroupId_ = 789012;
    focusWindowInfo.displayId_ = 345678;
    focusWindowInfo.pid_ = 901234;

    mockWindowAdapter->OnFocused(focusWindowInfo);

    std::vector<FocusChangeInfo> retrievedInfos;
    int32_t result = mockWindowAdapter->GetAllFocusWindowInfos(retrievedInfos);
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
    EXPECT_EQ(retrievedInfos.size(), 1);

    mockWindowAdapter->OnUnFocused(focusWindowInfo);

    int32_t result2 = mockWindowAdapter->GetAllFocusWindowInfos(retrievedInfos);
    EXPECT_EQ(result2, ErrorCode::NO_ERROR);
    EXPECT_EQ(retrievedInfos.size(), 0);

    mockWindowAdapter->OnUnFocused(focusWindowInfo);

    int32_t result3 = mockWindowAdapter->GetAllFocusWindowInfos(retrievedInfos);
    EXPECT_EQ(result3, ErrorCode::NO_ERROR);
    EXPECT_EQ(retrievedInfos.size(), 0);
}

/**
 * @tc.name: WindowAdapterMockTest_RegisterAllGroupInfoChangedListener_001
 * @tc.desc:
 * @tc.type: FUNC
 * @tc.require:
 */
HWTEST_F(WindowAdapterMockTest, WindowAdapterMockTest_RegisterAllGroupInfoChangedListener_001, TestSize.Level1)
{
    IMSA_HILOGI("WindowAdapterMockTest::WindowAdapterMockTest_RegisterAllGroupInfoChangedListener_001 start.");
    int32_t result = mockWindowAdapter->RegisterAllGroupInfoChangedListener();
    EXPECT_EQ(result, ErrorCode::NO_ERROR);
}
} // namespace MiscServices
} // namespace OHOS